\chapter{软件设计}
\section{需求分析}
\subsection{需求概述}
软件需要具有基本的用户界面，可以读取常用的CFD数据文件，并进行常用的可视化、后处理操作。软件需要在进行一定规模数据的后处理可视化时，确保依旧有良好的交互体验，因此对软件的效率有一定要求。此外，软件需要保证一定的鲁棒性，确保在常规使用中稳定运行。

\subsection{功能概述}
软件的功能主要分为3个版块：文件读写、可视化和后处理。
\begin{itemize}
    \item \textbf{文件读写} .软件可以读取二进制Tecplot文件（.plt）、CGNS文件（.cgns）、文本数组文件（无固定扩展名，一般为.txt）以及VTK格式（.vtk），将其转换为VTK的数据结构并进行后续的后处理可视化操作。读取的文件可以导出为VTK格式。
    
    读取、导出文件的用例如下。
    \begin{enumerate}
        \item 用户打开软件。
        \item 用户点击界面上的“读取文件”按钮。
        \item 用户在文件系统中选择需要打开的数据文件。
        \item 系统完成文件的读取。如果读取遇到错误，则会对用户进行提示，用户可以重新选择其他文件读取。
        \item 若文件读取成功，用户点击界面上的“导出文件”按钮。
        \item 用户选择导出文件的路径和文件名，以及文件的格式，并确认。
        \item 软件完成文件的导出。
    \end{enumerate}
    \item \textbf{可视化} 。对读取的数据进行可视化。对于三维数据，会以三维的方式渲染，可以调节数据渲染的方式（以散点、网格、面、箭头等)，调节渲染的参数（如是否显示、物体颜色等）。对于二维数据，会以折线图的形式绘制，并且提供了指数变换和对数变换，便于观察数据。

    进行一次可视化操作的用例如下。
    \begin{enumerate}
        \item 用户打开软件。
        \item 用户点击界面上的“读取文件”按钮。
        \item 用户在文件系统中选择需要打开的数据文件。
        \item 系统完成文件的读取。如果读取遇到错误，则会对用户进行提示，用户可以重新选择其他文件读取。
        \item 若文件读取成功，用户勾选界面上所需的可视化选项（如网格、面、图表等)。
        \item 软件使用勾选的可视化选项，以默认的相机设置、可视化参数进行渲染。
        \item 用户使用鼠标的点击、滚轮和拖拽等方式操作渲染界面。
        \item 软件对相机进行对应的调整，以新的相机设置进行渲染。
        \item 用户点击界面上的“可视化参数设置”按钮，然后进行可视化参数的调整。
        \item 软件以新的可视化参数进行渲染。
        \item 用户对可视化结果进行观察记录，进行数据分析。
    \end{enumerate}
    可视化观察流场时，可能获取需要流场某个位置具体的值，这个操作称为采点。采点可以通过数据本身的结构（如结构数据的每个点对应了一个三维索引坐标），也可以通过在屏幕上点击想要采点的位置，或是手动设置一个坐标点来完成。设置索引坐标采点的用例如下。
    \begin{enumerate}
        \item 用户打开软件。
        \item 用户点击界面上的“读取文件”按钮。
        \item 用户在文件系统中选择需要打开的数据文件。
        \item 系统完成文件的读取。如果读取遇到错误，则会对用户进行提示，用户可以重新选择其他文件读取。
        \item 用户打开采点菜单，设置需要采点的区域和索引坐标，然后点击确认。
        \item 软件根据索引值查询对应的点，并在界面上显示该点的各项属性值。
    \end{enumerate}
    使用3D坐标或是点击采点的用例如下。
    \begin{enumerate}
        \item 用户打开软件。
        \item 用户点击界面上的“读取文件”按钮。
        \item 用户在文件系统中选择需要打开的数据文件。
        \item 系统完成文件的读取。如果读取遇到错误，则会对用户进行提示，用户可以重新选择其他文件读取。
        \item 用户打开采点菜单，设置需要采点3D坐标并确认，或者打开点击采点，在需要采点的位置点击。
        \item 软件根据设置的3D坐标点，或是点击的点找到数据中对应的点，并在界面上显示该点的各项属性值。
    \end{enumerate}

    \item \textbf{后处理} 。软件提供了等势面、等值线和流线的后处理功能。将数据和后处理参数传入后可以得到经过后处理得到的数据，然后通过可视化显示出来。
    
    进行一次后处理操作的用例如下。
    \begin{enumerate}
        \item 用户打开软件。
        \item 用户点击界面上的“读取文件”按钮。
        \item 用户在文件系统中选择需要打开的数据文件。
        \item 系统完成文件的读取。如果读取遇到错误，则会对用户进行提示，用户可以重新选择其他文件读取。
        \item 若文件读取成功，用户勾选界面上所需的后处理选项（如等值线、等势面等)。
        \item 软件进行后处理计算，完成计算后将数据提交给可视化模块进行渲染。
        \item 用户可以观察到后处理的结果。
        \item 用户点击界面上的“后处理参数设置”按钮，然后进行后处理参数的调整。
        \item 软件以新的后处理参数进行计算、渲染。
        \item 用户对后处理结果进行观察记录，进行数据分析。
    \end{enumerate}
\end{itemize}

用户从读取文件、可视化操作、后处理操作到导出文件的流程可用以下序列图表示。

\begin{figure}[H]
    \centering
    \includegraphics[width=0.5\textwidth]{./images/placeholder}
    \caption{读取文件、可视化操作、后处理操作和导出文件的序列图}
\end{figure}

\section{架构和模块设计}
结合上述的需求分析，软件使用六个模块来完成上述的功能。以下是各模块的介绍。
\subsection{公共（Common）}
Common模块存有其他模块公用的结构和类。其中包括控制执行模式（同步或异步）的枚举、代表执行结果的枚举（成功、执行中或失败）、读取模式的枚举（几何数据、属性数据或二者）、读取类型的枚举（普通数据或边界数据）、文件信息类（包括文件路径、大小和类型等信息）以及区域信息类（一个区域信息可以包含几何数据和属性数据）。

软件中有多处使用了异步方法，因此需要引入执行结果和执行模式的枚举。因为数据文件中可能包含多类数据，所以提供了设置读取数据类型的枚举用于控制。一个区域信息是后处理可视化的基本单位，在多个模块被引用。

\begin{figure}[H]
    \centering
    \includegraphics[width=0.6\textwidth]{./images/Common-class}
    \caption{Common模块中的类图}
\end{figure}

\subsection{文件读写（IO）}
IO模块主要负责文件读写。IO模块对外只提供了一个接口和一个文件数据缓冲结构，外部通过调用这个接口来读取文件，并得到文件数据缓冲结构。文件数据缓冲结构包含了正在读取或以及完成读取的文件数据，通过其接口可以查询是否读取完成或获取区域信息。
IO对象的管理由IO模块内部完成，外部通过接口传入签名来指定文件类型，再通过文件数据缓冲结构获取文件数据，其中外部不涉及IO对象的创建、编辑和销毁。
\begin{figure}[H]
    \centering
    \includegraphics[width=0.4\textwidth]{./images/IO-class}
    \caption{IO模块中的类图}
\end{figure}

\subsection{三维场景管理与渲染（View）}
View模块主要包含一个场景管理类，用于管理和渲染三维场景。场景管理类由外部创建并使用，它包含了物体管理和设置、相机管理和设置以及场景交互的功能。物体管理使用单独的类，每一类物体（如3D物体、2D物体）对应了不同的管理类，而这些类都继承自同一个管理基类。通过场景管理对象可以创建需要的管理类，通过管理类的接口可以设置它管理的数据、是否显示、渲染方式和物体颜色等信息。此外，View模块和渲染窗口绑定，因此也包含交互（如鼠标、键盘事件）的处理。因为物体管理可能涉及到渲染相关的配置，所以物体管理类包含了渲染器对象的信息。

\begin{figure}[H]
    \centering
    \includegraphics[width=0.6\textwidth]{./images/View-class}
    \caption{View模块中的类图}
\end{figure}

\subsection{图表管理与绘制（Context）}
Context模块和View模块类似，主要包含一个图表管理类。图表管理类包含设置数据的接口，设置好数据后可以添加、删除折线图，配置颜色表、线段和端点类型、图表的坐标范围、图例等等图表绘制需要关心的内容。此外，图表管理类提供了自动适配大小的功能，开启后图表范围会根据数据自动适配。

\begin{figure}[H]
    \centering
    \includegraphics[width=0.4\textwidth]{./images/Context-class}
    \caption{Context模块中的类图}
\end{figure}

\subsection{后处理（Filter）}
Filter模块用于运行后处理算法。Filter模块向外只提供了数个接口，分别对应了各类后处理方法，包括箭头、等值线、等势面和流线等后处理。后处理的结果通过回调函数异步获取，通过View模块的物体管理类渲染出来，或是用作进一步的后处理。

\begin{figure}[H]
    \centering
    \includegraphics[width=0.4\textwidth]{./images/Filter-class}
    \caption{Filter模块中的类图}
\end{figure}

\subsection{用户界面（Visualization）}
Visualization模块主要包含用户界面，且作为项目入口协调管理各个模块的工作。Visualization模块包含了主函数，其中初始化各模块并创建了主窗口。软件的界面使用QT Creator制作，通过QT的信号模式获取控件的状态，在信号函数中处理各类事件，实现交互的功能。

本模块的类主要继承自QT提供的基类，如QT主窗口类QMainWindow和QT对话框类Dialog，其分别用于软件主窗口、弹出菜单的制作。

\subsection{软件架构}
除了Common模块和Visualization模块外，其余四个模块相对独立，没有互相依赖的关系，实现了模块间的低耦合。各模块间的配合是由Visualization模块负责，模块间的关系如下图。
\begin{figure}[H]
    \centering
    \includegraphics[width=0.5\textwidth]{./images/Components-diagram}
    \caption{软件构件图}
\end{figure}
